package service

import (
	"errors"
	"fmt"
	log "github.com/sirupsen/logrus"
	"io/ioutil"
	"os"
	"path/filepath"
	"simple-app/lib/id"
	"simple-app/lib/jwt"
	"simple-app/modules/dao"
	"simple-app/structs/dto"
	"simple-app/structs/tables"
	"strings"
	"time"
)

var UserService = new(userService)

type userService struct {
}

// VerifyCode 检查验证码是否合法
func (ser userService) VerifyCode(ver dto.VeryCode) bool {
	return true
}

// UserLogin 用户登录，返回token
func (ser userService) UserLogin(loginAccount dto.LoginAccount) (result dto.LoginSuccess, base jwt.BaseClaims, err error) {
	var (
		user         tables.User
		rs           []string
		accessToken  string
		refreshToken string
	)
	user, err = dao.UserDao.FindUserByAccount(loginAccount.Username)
	if err != nil {
		return
	}
	if user.Password != loginAccount.Password {
		return result, base, fmt.Errorf("密码错误: %v ", loginAccount)
	}
	j := jwt.NewJWT()
	rs = ser.getRoles(user.RoleCode)
	base = jwt.BaseClaims{
		UserID:    user.UserId,
		Username:  user.Account,
		Nickname:  user.Nickname,
		AccountLv: user.AccountLv,
		Role:      rs,
	}
	accessToken, err = j.CreateToken(base, jwt.JWTAccessTime)
	refreshToken, err = j.CreateToken(base, jwt.JWTRefreshTime)
	result = dto.LoginSuccess{
		Username:     user.Nickname,
		Roles:        rs,
		AccessToken:  accessToken,
		RefreshToken: refreshToken,
		Expires:      (time.Now().Unix() + jwt.JWTAccessTime) * 1000,
	}
	return
}

func (ser userService) getRoles(roleCode string) (rs []string) {
	return strings.Split(roleCode, ",")
}

func (ser userService) GetRouterTreeForFile() (bs []byte, err error) {
	var (
		p string
	)
	if p, err = os.Executable(); err != nil {
		log.Error("os.Executable()", p, err)
		return
	}
	return ioutil.ReadFile(filepath.Join(filepath.Dir(p), "web_router.json"))
}

func (ser userService) RefreshToken(self *jwt.CustomClaims) (result dto.LoginSuccess, base jwt.BaseClaims, err error) {
	var (
		user         tables.User
		rs           []string
		accessToken  string
		refreshToken string
	)
	user, err = dao.UserDao.FindById(self.UserID)
	if err != nil {
		return
	}
	j := jwt.NewJWT()
	rs = ser.getRoles(user.RoleCode)
	base = jwt.BaseClaims{
		UserID:    user.UserId,
		Username:  user.Account,
		Nickname:  user.Nickname,
		AccountLv: user.AccountLv,
		Role:      rs,
	}
	accessToken, err = j.CreateToken(base, jwt.JWTAccessTime)
	refreshToken, err = j.CreateToken(base, jwt.JWTRefreshTime)
	result = dto.LoginSuccess{
		Username:     user.Nickname,
		Roles:        rs,
		AccessToken:  accessToken,
		RefreshToken: refreshToken,
		Expires:      (time.Now().Unix() + jwt.JWTAccessTime) * 1000,
	}
	return
}

func (ser userService) Register(in dto.UserRegister) error {
	var (
		b        bool
		err      error
		referrer tables.User
	)
	// 检查账户是否已经存在
	b, err = dao.UserDao.CheckAccountIsExist(in.Phone)
	if err != nil {
		log.Error(err)
		return err
	}
	if b {
		return errors.New("账户已经存在")
	}
	if referrer, err = dao.UserDao.FindReferrerByReferCode(in.ReferrerPhone); err != nil {
		return err
	}
	// 不存在就添加用户
	m := tables.User{
		UserId:            id.GetSnowId(),
		Account:           in.Phone,
		Password:          in.Password,
		Status:            tables.UserStatusUnactivated,
		AccountLv:         tables.AccountLvForUser,
		Nickname:          in.NickName,
		Phone:             in.Phone,
		ReferrerId:        referrer.UserId,
		TokenMoney:        0,
		Score:             0,
		RoleCode:          "user",
		InviteCode:        "",
		ResidueAuctionNum: 0,
		PrivilegeEndTime:  0,
		PrivilegeNum:      0,
		CreatedAt:         time.Now().Unix(),
		DeletedAt:         0,
	}
	if err = dao.UserDao.CreateAccount(&m); err != nil {
		return err
	}
	return nil
}
